import { application } from "../../hcl/Application.js";
import { hcl } from "../../hcl/HCL.js";
import { TOpenDialog, TForm } from "../../hcl/Forms.js";
import { TRichAudio, TPlayState } from "../../hcl/ExtCtrls.js";
import { TLable, TCheckBox } from "../../hcl/StdCtrls.js";
import { TAlign } from "../../hcl/Controls.js";
import { TBrushStyle, TColor } from "../../hcl/Graphics.js";
import { theme } from "../../hcl/theme.js";

let mainForm = new TForm(hcl.width, hcl.height);
mainForm.caption = "视觉音乐播放器";
mainForm.captionBar.transparent = false;
mainForm.captionBar.color = theme.backgroundStaticColor;

let btnOpen = mainForm.captionBar.addButton("打开mp3文件");
btnOpen.hint = "打开一个音频文件";
btnOpen.onClick = () => {
    TOpenDialog.execute(String.format("{0}", ".mp3"), (openDlg) => {
        lblMusic.text = openDlg.firstFile.name;
        audio.close();
        audio = null;
        audio = new TRichAudio();
        initAudio(audio);
        audio.loadFromFile(openDlg.firstFile);
    });
}

let btnPlay = mainForm.captionBar.addButton("播放/暂停");
btnPlay.enabled = false;

let lblTime = new TLable("00:00:00 / 00:00:00");
lblTime.width = 150;
lblTime.align = TAlign.Left;
mainForm.captionBar.addControl(lblTime);

let lblMusic = new TLable("部分mp3解码不正确无法播放，请换一首！");
lblMusic.align = TAlign.Left;
mainForm.captionBar.addControl(lblMusic);

let chkZoom = new TCheckBox("自动缩放比例");
chkZoom.align = TAlign.Left;
mainForm.captionBar.addControl(chkZoom);

let vAnimatHandle = 0;

function drawMeter() {
    mainForm.update();
    vAnimatHandle = requestAnimationFrame(drawMeter);
}

btnPlay.onClick = () => {
    if (audio.state == TPlayState.Play)
        audio.pause();
    else
        audio.play();
}

let vDuration = "";
let audio = new TRichAudio();

function initAudio(audio) {
    audio.autoPlay = true;
    audio.onStateChanged = () => {
        switch (audio.state) {
            case TPlayState.Loading:
                btnPlay.text = "加载...";
                btnPlay.enabled = false;
                break;
    
            case TPlayState.Loaded:
                btnPlay.text = "播放";
                btnPlay.enabled = true;
                vDuration = secondToTime(audio.duration);
                lblTime.text = "00:00:00 / " + vDuration
                
                break;
    
            case TPlayState.Play:
                btnPlay.text = "暂停";
                vAnimatHandle = requestAnimationFrame(drawMeter);
                break;
    
            case TPlayState.Pause:
            case TPlayState.Stop:
                btnPlay.text = "播放";
                if (vAnimatHandle > 0) {
                    cancelAnimationFrame(vAnimatHandle);
                    vAnimatHandle = 0;
                }
    
                break;
        }
    }

    audio.onProgress = () => {
        lblTime.text = secondToTime(audio.second) + " / " + vDuration;
    }
}

function secondToTime(seconds) {
    seconds = Math.ceil(seconds);
    let vMin, vSec;
    if (seconds >= 3600) {
        vMin = Math.trunc(seconds % 3600 / 60);
        if (vMin < 10)
            vMin = "0" + vMin;

        vSec = seconds % 60;
        if (vSec < 10)
            vSec = "0" + vSec;

        return String.format("{0}:{1}:{2}", Math.trunc(seconds / 3600), vMin, vSec);
    }
    else if (seconds >= 60) {
        vMin = Math.trunc(seconds / 60);
        if (vMin < 10)
            vMin = "0" + vMin;

        vSec = seconds % 60;
        if (vSec < 10)
            vSec = "0" + vSec;
        return vMin + ":" + vSec;
    } else {
        if (seconds < 10)
            seconds = "0" + seconds;
        return String.format("00:{0}", seconds);
    }
}

let vWidth, vHeight, vMeterNum, vCapHeight = 2, vCapArray = [];

mainForm.onResize = () => {
    vWidth = mainForm.width,
    vHeight = mainForm.height - 2,
    //vGapW = 2, // 能量条间的间距
    vMeterNum = Math.trunc(vWidth / (10 + 2));  // 画多少条
}

mainForm.onPaintBackground = (hclCanvas) => {
    if (audio.state != TPlayState.Play)
        return;
    
    let vGradient = hclCanvas.createLinearGradient(0, 0, 0, vHeight);
    vGradient.addColorStop(1, "#0f0");
    vGradient.addColorStop(0.5, "#ff0");
    vGradient.addColorStop(0, "#f00");

    let vArray = new Uint8Array(audio.analyser.frequencyBinCount);
    audio.analyser.getByteFrequencyData(vArray);
    let vStep = Math.round(vArray.length / vMeterNum);  // 采样步长
    let vValue, vLeft = 0;
    for (let i = 0; i < vMeterNum; i++) {
        vValue = chkZoom.checked ? vArray[i * vStep] * vHeight / 255 : vArray[i * vStep];

        if (vCapArray.length < vMeterNum)
            vCapArray.push(vValue);  // 初始化保存帽头位置的数组，将第一个画面的数据压入其中

        hclCanvas.brush.color = TColor.White;
        // 开始绘制帽头
        if (vValue < vCapArray[i]) {  // 如果当前值小于之前值
            hclCanvas.fillBounds(vLeft, vHeight - (--vCapArray[i]), 10, vCapHeight);
        } else {
            hclCanvas.fillBounds(vLeft, vHeight - vValue, 10, vCapHeight);
            vCapArray[i] = vValue;
        }

        hclCanvas.brush.style = TBrushStyle.Gradient;
        hclCanvas.gradientBrush = vGradient;
        hclCanvas.fillBounds(vLeft, vHeight - vValue + vCapHeight, 10, vHeight);
        vLeft += 12;
    }
}

theme.backgroundStaticColor = TColor.Black;
application.icon.src = "icon.png";
application.title = "音乐播放器";
application.addForm(mainForm);
hcl.homePath = "../../hcl/";
hcl.autoWidth = true;
application.run();